#include "vpd_system.h"
#include <string.h>
#include "vpdCheckMessage.h"
#ifndef NO_FPGA_SDK_ENABLE
    #include "lwip/sockets.h"
	#include "qspi_tcp_update.h"
#endif
char	firmWareBuffer[16*1024*1024];
u32		micMaskValue[8];
#ifdef WIN32
    #include <winsock2.h>
    #include <windows.h>
#else
extern int send_data(void* sendBuffer, uint16_t sendSize);
#endif
extern fpgaState	gState;
TickType_t xStartCount;
static void sendReplyMessage(vpdSystem *sys,char *msg);

static int sendData(vpdSystem *sys,void *buf,int len)
{

		int ret;
#ifdef WIN32
    if(sys->socketFd!=NULL)
        send(sys->socketFd,buf,len,0);
#else
   // 	send_data(buf,len);
   ret= write(sys->socketFd,buf,len);
#endif
 //   printf("%s  len: %d  ret:\n",__func__,len,ret);
 //   sys->p_vpdCtrl->getData(buf);
  //  sys->p_vpdCtrl->startModule();
  //  sys->p_vpdCtrl->stopModule();

    return ret;

}
static void updateFirmware(vpdSystem *sys,char *fwBuffer,int len)
{
    sendReplyMessage(sys,"start update firmware!!!\n");
    sendReplyMessage(sys,"start Erase Flash !!!\n");
    qspi_update((u8*)fwBuffer,len);
}
static void sendReplyMessage(vpdSystem *sys,char *msg)
{
    int len=strlen(msg)+1;
    sys->p_globalStReplyMessge->head.invokeID=sys->invokeId++;
    sys->p_globalStReplyMessge->head.length=sys->headLen.LEN_REPLY_MESSAGE+len;

    sys->p_globalStReplyMessge->length=len;
    sendData(sys,(char*)sys->p_globalStReplyMessge,sizeof(objStReplyMessage));
    sendData(sys,msg,len);
    printf("%s",msg);
}
static objStRawData * objStRawDataHeadInit()
{
    objStRawData *obj=malloc(sizeof(objStRawData));
    obj->head.cmd=DATA_MESSAGE_D2H;
    obj->head.invokeID=0;
    obj->head.reserved=0;
    obj->head.objCnts=1;

    obj->objID=OBJ_ID_RAW_DATA_STREAM;
    obj->typeID=R_VERSION;
    //  obj->length=36+sys->rawdataBufferSize;
    obj->groupID=0;
    //obj->channelsNums=sys->parameter.curChannels;
    //obj->samplesNums=sys->parameter.rawdataLen;
    obj->mode=0;
    obj->reserved=0;
    obj->lsb=0.1;
    obj->ts=0;
    obj->dt=1;//For test
    obj->factor=1.1;
    //obj->dt=sys->parameter.dt;
    //obj->head.length=4+44+len;
    return obj;
}
static objStRawFFT * objStRawFFTHeadInit()
{
    objStRawFFT *obj=malloc(sizeof(objStRawFFT));
    obj->head.cmd=DATA_MESSAGE_D2H;
    obj->head.invokeID=0;
    obj->head.reserved=0;
    obj->head.objCnts=1;
    obj->objID=OBJ_ID_RAW_FFT;
	obj->typeID=R_VERSION;
    obj->ts=0;
    obj->filtered=0;
    obj->df=1;
    obj->freqMin=1000;
    obj->freqMax=10000;
    return obj;
}
void objStOtherHeadInit(vpdSystem *sys)
{
   // sys->p_globalStJpeg
    objStJpeg  *obj= malloc(sizeof(objStJpeg));     //for jpeg head
    obj->head.cmd=DATA_MESSAGE_D2H;
    obj->head.invokeID=0;
    obj->head.reserved=0;
    obj->head.objCnts=1;
    obj->objID=OBJ_ID_VIDEO_DATA;
    obj->typeID=R_VERSION;
    obj->ts=0;
    obj->hPix=1920;
    obj->vPix=1080;
    sys->p_globalStJpeg=obj;

    objStOneData *obj2=malloc(sizeof(objStOneData));
    obj2->head.cmd=DATA_MESSAGE_D2H;
    obj2->head.invokeID=0;
    obj2->head.reserved=0;
    obj2->head.objCnts=1;
    obj2->objID=OBJ_ID_RAW_DATA;
    obj2->typeID=R_VERSION;
    obj2->micIndex=0;
    obj2->dt=(float)1.0f/(float)51200;     //Sample Rate
    obj2->factor=0.001;
    sys->p_globalStOneData=obj2;

    objStAcoustic *obj3=malloc(sizeof(objStAcoustic));
    obj3->head.cmd=DATA_MESSAGE_D2H;
    obj3->head.invokeID=0;
    obj3->head.reserved=0;
    obj3->head.objCnts=1;
    obj3->objID=OBJ_ID_ACOUSTIC_VIDEO_DATA;
    obj3->typeID=R_VERSION;
    obj3->freqMin=0;
    obj3->freqMax=200000;
    obj3->distance=1;
    sys->p_globalStAcoustic=obj3;

    objStOneFFT *obj4=malloc(sizeof(objStOneFFT));
    obj4->head.cmd=DATA_MESSAGE_D2H;
    obj4->head.invokeID=0;
    obj4->head.reserved=0;
    obj4->head.objCnts=1;
    obj4->objID=OBJ_ID_SPECTRUMDATA;
    obj4->typeID=R_VERSION;
    obj4->freqMin=0;
    obj4->freqMax=200000;
    obj4->df=0;
    obj4->filtered=0;
    obj4->fftSize=1024;
    obj4->micIndex=1;
    sys->p_globalStOneFFT=obj4;

    objStCommonStatus *obj5=malloc(sizeof(objStCommonStatus));
    obj5->head.cmd=DATA_MESSAGE_D2H;
    obj5->head.invokeID=0;
    obj5->head.reserved=0;
    obj5->head.objCnts=1;
    obj5->objID=OBJ_ID_COMMON_STATUS;
    obj5->typeID=DT_COMMON_STATUS;
    sys->p_globalStcommonStatus=obj5;

    objStReplyMessage *obj6=malloc(sizeof(objStReplyMessage));
    obj6->head.cmd=DATA_MESSAGE_D2H;
    obj6->head.invokeID=0;
    obj6->head.reserved=0;
    obj6->head.objCnts=1;
    obj6->objID=OBJ_ID_REPLY_MESSAGE;
    obj6->typeID=R_VERSION;
    sys->p_globalStReplyMessge=obj6;

}
static void  generateIdResponse(vpdSystem *sys)
{
    sendData(sys,sys->idInfo,sizeof(resIdentification));
    printf("%s  %d \n",__func__,__LINE__);
    return ;
}

static void  generateFFTData(vpdSystem *sys,uint32_t len)
{
    sys->p_globalStRawFFT->head.invokeID++;
    sys->p_globalStRawFFT->ts=sys->timestamps;
    sys->p_globalStRawFFT->length=len+sys->headLen.BODY_RAW_FFT;
    sys->p_globalStRawFFT->head.length=sys->headLen.LEN_RAW_FFT+len;
  //  sys->p_globalStRawFFT->freqMin=sys->mSettings.freqMin;
 //   sys->p_globalStRawFFT->freqMax=sys->mSettings.freqMax;
    sys->m_rawfftTs+=len;
    sendData(sys,sys->p_globalStRawFFT,sizeof(objStRawFFT));
    return ;
}
static void generateRawData(vpdSystem *sys,uint32_t len)
{
    sys->p_globalStRawData->head.invokeID++;
    sys->p_globalStRawData->ts=sys->timestamps;
    sys->p_globalStRawData->head.length=sys->headLen.LEN_RAW_DATA+len;
    sys->p_globalStRawData->length=sys->headLen.BODY_RAW_DATA+len;
    sendData(sys,sys->p_globalStRawData,sizeof(objStRawData));
  //  printf("%s ts:%lu %d %d  %d %d \n",__func__,sys->p_globalStRawData->ts,sizeof(objStRawData),len,sys->p_globalStRawData->head.length,sys->p_globalStRawData->length);
    return ;
}
static void generateJpegData(vpdSystem *sys,uint32_t len)
{
    sys->p_globalStJpeg->head.invokeID++;
    sys->p_globalStJpeg->head.length=sys->headLen.LEN_JPEG+len;
    sys->p_globalStJpeg->ts=sys->timestamps;
    sys->p_globalStJpeg->length=sys->headLen.BODY_JPEG+len;
    sendData(sys,sys->p_globalStJpeg,sizeof(objStJpeg));
  //  sys->p_globalStJpeg->
}
static void generateOneData(vpdSystem *sys,uint32_t len)
{
    sys->p_globalStOneData->head.invokeID++;
    sys->p_globalStOneData->head.length=sys->headLen.LEN_ONE_DATA+len;
    sys->p_globalStOneData->ts=sys->timestamps;
    sys->p_globalStOneData->micIndex=sys->mSettings.micIndex;
    sys->p_globalStOneData->length=len+sys->headLen.BODY_ONE_DATA;
    sendData(sys,sys->p_globalStOneData,sizeof(objStOneData));
    //  sys->p_globalStJpeg->
}
static void generateOneFFT(vpdSystem *sys,uint32_t len)
{
    sys->p_globalStOneFFT->head.invokeID++;
    sys->p_globalStOneFFT->head.length=sys->headLen.LEN_ONE_FFT+len;
    sys->p_globalStOneFFT->ts=sys->timestamps;
    sys->p_globalStOneFFT->length=len+sys->headLen.BODY_ONE_FFT;
    sendData(sys,sys->p_globalStOneFFT,sizeof(objStOneFFT));
    //  sys->p_globalStJpeg->
}

static void generateAcousData(vpdSystem *sys,uint32_t len)
{
    sys->p_globalStAcoustic->head.invokeID++;
    sys->p_globalStAcoustic->head.length=sys->headLen.LEN_ACOUS+len;
    sys->p_globalStAcoustic->ts=sys->timestamps;
    sys->p_globalStAcoustic->length=len+sys->headLen.BODY_ACOUS;
    sendData(sys,sys->p_globalStAcoustic,sizeof(objStAcoustic));
}
static int generateObjReadResponse(vpdSystem *sys,uint8_t objID,uint8_t invokeId)
{
    if(objID==OBJ_ID_COMMON_STATUS)
    {
        struct OBJ_ST_COMMONSTATUS res;
        res.objID=OBJ_ID_COMMON_STATUS;
        res.typeID=DT_COMMON_STATUS;
        res.length=12;
        res.errorCode=0;
        res.deviceState=sys->devNeedStatus;
        res.subState=sys->devSubStatus;
        memcpy(sys->objRR.obj.objBuffer,&res,sizeof(struct OBJ_ST_COMMONSTATUS));
        sys->objRR.obj.invokeId=invokeId;
        sys->objRR.obj.dataLength=4+sizeof(struct OBJ_ST_COMMONSTATUS);
        sys->objRR.obj.objNums=1;
        sys->objRR.obj.status=0;
          sys->objRR.len=sizeof(struct OBJ_ST_COMMONSTATUS)+16;
        return sys->objRR.len;

    }
    if(objID==OBJ_ID_CAMERA_RESOLUTION)
    {

    }

    return 0;
}
static resStatus * generateStatusResponse(uint8_t type,uint8_t invokeId)
{
    resStatus *res=malloc(sizeof(resStatus));

    res->invokeID=invokeId;
    res->resvered=0;
    res->dataLen=0;
    res->cmd=type&0x7F;
    switch (type)
    {
    case REQ_CMD_RESET:
    case REQ_CMD_IDENTIFICATION:
    case REQ_CMD_PREPARE_STATE:
    case REQ_CMD_FINISH_STATE:
    case REQ_CMD_START_PROCEDURE:
    case REQ_CMD_STOP_PROCEDURE:
        res->status=0;
        break;
    case REQ_CMD_WRITE_DATA_OBJECT:
        res->status=0;
        break;
    }
    return res;
}
static void * parseObjStruct(vpdSystem *sys,char *buf,int len)
{
   // memcpy(sys->recvBuf+sys->bufPos,buf,len);
    char *cmdBuffer=buf;        //sys->recvBuf;
    uint8_t cmdType=*buf;
    uint8_t invokeId=*(buf+1);
    //  uint16_t reserved=*(buf+2);
    uint32_t objLen=*(buf+4);
    printf("%s %d  %d  %d %d %d \n",__func__,__LINE__,cmdType,invokeId,len,objLen);
    if(cmdType==REQ_CMD_IDENTIFICATION)
    {
        //  vpdInfo *info=generateIdResponse(sys);
        sys->idInfo->invokeId=invokeId;
        sendData(sys, sys->idInfo, sizeof(resIdentification));

    }else if(cmdType==REQ_CMD_WRITE_DATA_OBJECT)
    {
        resStatus *reply=generateStatusResponse(cmdType,invokeId);
        sendData(sys, reply, sizeof(resStatus));
        free(reply);


    }else if(cmdType==REQ_CMD_READ_DATA_OBJECT)
    {
        reqReadObj *msg=(reqReadObj*)(cmdBuffer);
        for(int i=0;i<msg->objCnts;i++)
        {
            int bufLen=generateObjReadResponse(sys,msg->objIds[i],invokeId);
            printf("LINE_%d cmdType:0x%x len: %d objs:%d objID:%x \n",
                   __LINE__,cmdType,msg->length,msg->objCnts,msg->objIds[i]);

            sendData(sys, &sys->objRR.obj, bufLen);
        }



    }else if(cmdType==REQ_CMD_PREPARE_STATE)

        {
            sys->devSubStatus=SUB_FINISHED;
            resStatus *reply=generateStatusResponse(cmdType,invokeId);
            sendData(sys, reply, sizeof(resStatus));
            free(reply);

        }
    else {
        resStatus *reply=generateStatusResponse(cmdType,invokeId);
        printf("\n res Info:");
     //   char *rep=(char*)reply;
      //  for(int x=0;x<sizeof(resStatus);x++)
       //     printf("%0.2x ",*(rep++));
        printf("\n");
        sendData(sys, reply, sizeof(resStatus));
        free(reply);
    }
    return NULL;
}
//void parseAndReponseMessage(vpdSystem *sys,char *buf,int len)


void processVpdMsg(vpdSystem *sys,VPD_MESSAGE *msg)
{

	//0x55AA0051
//	printf("%s   MSG_HEAD:%x  \n",__func__,msg->MSG_HEAD);
	u8  chgFps=0;
	u8  valu8=0;
	if(msg->MSG_HEAD!=0x55AA0051)
	{
		printf("%s   MSG_HEAD ERROR :%x  \n",__func__,msg->MSG_HEAD);
		return ;
	}
    uint32_t *arryInt=(uint32_t *)msg->MSG_ARRAY;
    printf("%s   id:%x  type:%x  length:%x \n",__func__,msg->MSG_ID,msg->MSG_TYPE,msg->MSG_LENGTH);
    switch(msg->MSG_TYPE)
        {

        case MSG_SET_SAMPLE_RATE:
        	{
        		chgFps=1;
        		if(*arryInt<SR_MAX_NULL)
        		{
        			sys->mSettings.sampleRate=*arryInt;
        			if(sys->vpdStatus==STATUS_IDLE)
        			{
        				update_settings(SAMP_RATE, arryInt);
        			}
        		}
        		printf("%s rate:%d \n",__func__,sys->mSettings.sampleRate);
        	}

            break;
        case MSG_SET_RAWFFT_FPS:
        	sys->mSettings.beamFPS=*arryInt;
        	printf("msg set rawfft fps: %d \n",sys->mSettings.beamFPS);
        	chgFps=1;
        	break;
        case MSG_HEART_RATE:
        {
    	    	printf("response msg heart rate \n");
    	    	//sys->generateObjReadResponse(sys,OBJ_ID_COMMON_STATUS);
    	    	sys->m_heartRateFlag=1;
        	break;
        }
        case MSG_UPDATE_FPGA:
        {
            sys->vpdStatus=STATUS_UPDATE;
            uint64_t    *val=(uint64_t*)msg->MSG_ARRAY;
            sys->fwInfo.length=val[0];
            sys->fwInfo.checkSum=val[1];
            sys->fwInfo.upFlag=1;
            sys->fwInfo.buf=firmWareBuffer;
            printf("update firmware: len:%llu sum:%2x buf:%x \n",sys->fwInfo.length,sys->fwInfo.checkSum,sys->fwInfo.buf);
        }
        break;
        case MSG_SET_TRIGGER:
        	valu8=msg->MSG_ARRAY[0];
       		set_trigger_val(valu8);
        	break;
        case MSG_SET_TRIGGER_MODE:
        	valu8=msg->MSG_ARRAY[0];
       		set_sync_mode(valu8);
            break;
        case MSG_SET_MASTER:
        	valu8=msg->MSG_ARRAY[0];
        	printf("masterMode: %u \n",valu8);
        	break;
        case MSG_SET_MIC_DELAY:
        	valu8=msg->MSG_ARRAY[0];
        	set_mic_delay(valu8);
        	printf("set mic xx delay:%2x \n",valu8);
        	break;
        case MSG_SET_FILTER_COE:
        {
        	uint8_t *pTmp=(uint8_t*)&msg->MSG_LENGTH;
        	sys->m_coeBuf.id=pTmp[2];
        	sys->m_coeBuf.max=pTmp[1];
        	uint8_t nums=pTmp[0];
        	float *val=(float*)msg->MSG_ARRAY;

        	for(int i=0;i<nums;i++)
        		sys->m_coeBuf.val[sys->m_coeBuf.index++]=val[i];
        	printf("set filter id:%2x coe max:%2x  index:%2x \n",sys->m_coeBuf.id,sys->m_coeBuf.max, sys->m_coeBuf.index);
        	if(sys->m_coeBuf.max==sys->m_coeBuf.index)
        	{
        		sys->m_coeBuf.index=0;
        		set_filter_coe(sys->m_coeBuf.id,sys->m_coeBuf.val,sys->m_coeBuf.max);
        	   	printf("set filter coe max:%2x  index:%2x \n",sys->m_coeBuf.max, sys->m_coeBuf.index);
        	}
        }break;
        case MSG_SET_MIC_CHAN_REMAP:
        {
        	uint8_t *pTmp=(uint8_t*)&msg->MSG_LENGTH;
        	sys->m_micMap.max=pTmp[1];
        	uint8_t nums=pTmp[0];
        	uint8_t *val=(uint8_t*)msg->MSG_ARRAY;
        	for(int i=0;i<nums;i++)
        		sys->m_micMap.val[sys->m_micMap.index++]=val[i];
        	printf("set m_micMap: mic max:%2x  index:%2x \n",sys->m_micMap.max, sys->m_micMap.index);
        	if(sys->m_micMap.max<=sys->m_micMap.index)
        	{
        		sys->m_micMap.index=0;
        		set_mic_map(sys->m_micMap.val,sys->m_micMap.max);
        	   	printf("set_mic_map max:%2x  index:%2x \n",sys->m_micMap.max, sys->m_micMap.index);
        	}
        }break;
        case MSG_SET_MIC_MASK:
        {
        	if(msg->MSG_LENGTH==8)
        	{
        		printf("set_mic_mask " );
				for(int i=0;i<msg->MSG_LENGTH;i++)
				{
					micMaskValue[i]=arryInt[i];
					printf(" %08x ",micMaskValue[i]);
				}
				printf("\n");
				set_mic_mask(micMaskValue,8);
        	}
        }
        	break;
        case MSG_SET_MIC_CHAN_SIZE:
        	printf("set_mic_size: %u \n",msg->MSG_ARRAY[0]);
        	if(msg->MSG_ARRAY[0]==144)
        		sound_module_mic_set(144);
        	else
        		sound_module_mic_set(176);
        	break;
    case MSG_START:
    {
    	if(msg->MSG_ARRAY[0]==0)
    		sys->vpdStatus=STATUS_MEASURING;
    	else if(msg->MSG_ARRAY[0]==1)
    		sys->vpdStatus=STATUS_STREAMING;
        set_beam_fps(sys->mSettings.beamFPS);
        start_sound_module();
        sys->xStart = xTaskGetTickCount();

    }
        break;
    case MSG_STOP:
        sys->vpdStatus=STATUS_IDLE;
        stop_sound_module();
        break;
    case MSG_SET_LIGHT:
    	if(msg->MSG_ARRAY[0]==0)
    		set_led_status(0);
    	else
    		set_led_status(1);
    	printf("set led status %d \n",msg->MSG_ARRAY[0]);
    	break;

    case MSG_SET_MIC_INDEX:
    	sys->mSettings.micIndex=msg->MSG_ARRAY[0];
    	printf("msg set micIndex: %d \n",sys->mSettings.micIndex);
    	break;

    case MSG_SET_FREQ_RANGE:
		sys->mSettings.freqMin=*(arryInt);
		sys->mSettings.freqMax=*(arryInt+1);
		gState.changeFreq=1;

		printf("MSG_SET_FREQ_RANGE min:%d  max:%d \n",sys->mSettings.freqMin,sys->mSettings.freqMax);
	//	update_vpd_freq_range(sys->mSettings.freqMin,sys->mSettings.freqMax);

		break;
    case MSG_SET_TCP_DATA:
    {
        sys->tcpSendMask.mRawdataEn=msg->MSG_ARRAY[0];
        sys->tcpSendMask.mOnedataEn=msg->MSG_ARRAY[1];
        sys->tcpSendMask.mRawFFTEn=msg->MSG_ARRAY[2];
        sys->tcpSendMask.mOneFFTEn=msg->MSG_ARRAY[3];
        sys->tcpSendMask.mPicEn=msg->MSG_ARRAY[4];
        sys->tcpSendMask.mAcousEn=msg->MSG_ARRAY[5];
		if(sys->tcpSendMask.mRawdataEn==1)
		{
			set_beam_fps(sys->mSettings.beamFPS);
		}
        printf("%d  %u  %u  %u  \n",__LINE__,sys->tcpSendMask.mRawdataEn,sys->tcpSendMask.mOnedataEn,sys->tcpSendMask.mRawFFTEn);
        printf("%d  %u  %u  %u  \n",__LINE__,sys->tcpSendMask.mOneFFTEn,sys->tcpSendMask.mPicEn,sys->tcpSendMask.mAcousEn);
        chgFps=1;
        break;
    }
    case MSG_GET_FILTER_COE:
    	printf("get filter id:%2x   \n",sys->m_coeBuf.id);
    	float vals[40];
    	get_filter_coe(sys->m_coeBuf.id,vals,40);
    	break;
    default:
        break;
    }
    return ;
}
void fillFirmwareBuffer(vpdSystem *sys,char *buf,int len)
{
    if(sys->fwInfo.upFlag&&sys->fwInfo.buf!=NULL)
    {
        if(sys->fwInfo.length>sys->fwInfo.index)
        {
            memcpy(sys->fwInfo.buf+sys->fwInfo.index,buf,len);
            sys->fwInfo.index+=len;
            uint8_t percent=(sys->fwInfo.index*10)/sys->fwInfo.length;
            if(sys->fwInfo.upPercent!=percent)
            {
                sys->fwInfo.upPercent=percent;
                sprintf(sys->tempMsg,"Receive %d%%",sys->fwInfo.upPercent*10);
                printf("%s\n",sys->tempMsg);
                sendReplyMessage(sys,sys->tempMsg);
            }

            if(sys->fwInfo.length==sys->fwInfo.index)
            {
                uint16_t checkSum=crc16_ccitt(sys->fwInfo.buf,sys->fwInfo.length);
                printf("%s %d  %d sum:0x%2x 0x%2x \n",__func__,sys->fwInfo.length,sys->fwInfo.index,checkSum,sys->fwInfo.checkSum);
                if(sys->fwInfo.checkSum==checkSum)
                {
                    sprintf(sys->tempMsg,"Receive Success size:%d checkSum:0x%llx",sys->fwInfo.length,checkSum);
                    sendReplyMessage(sys,sys->tempMsg);
                    updateFirmware(sys,sys->fwInfo.buf,sys->fwInfo.length);
                }
            }
        }
      //  printf("%s %d  %d \n",__func__,sys->fwInfo.length,sys->fwInfo.index);
      //  if(sys->m_fwBuf.length==sys->m_fwBuf.index)
       //         sys->m_fwBuf.upFlag=false;
    }
}
void parseAndReponseMessage(vpdSystem *sys,char *buf,int len)
{
    int vpdSize=sizeof(VPD_MESSAGE);
    int restBytes=len;
    char *pBuf=buf;
    if(sys->m_restBuf.len>0)
    {
        int needBytes=vpdSize-sys->m_restBuf.len;
        if(needBytes>len)            //Need More bytes for one cmd
        {
            memcpy(sys->m_restBuf.buf+sys->m_restBuf.len,buf,len);
            sys->m_restBuf.len+=len;
            return ;

        }else{
            memcpy(sys->pVpdMsg,sys->m_restBuf.buf,sys->m_restBuf.len);
            memcpy(sys->pVpdMsg+sys->m_restBuf.len,pBuf,needBytes);
            processVpdMsg(sys,sys->pVpdMsg);
            pBuf+=needBytes;
            restBytes=len-needBytes;            //the rest bytes
            sys->m_restBuf.len=0;

            if(sys->fwInfo.upFlag)         // if receive update in nulti cmds
            {
                fillFirmwareBuffer(sys,pBuf,restBytes);
                return;
            }

            if(restBytes==0)
                return;
        }
    }
    if(sys->fwInfo.upFlag)     //if in update mode
    {
        fillFirmwareBuffer(sys,pBuf,restBytes);
    }else{                      //if in nomal mode

        for(;restBytes>=vpdSize;)
        {
            memcpy(sys->pVpdMsg,pBuf,vpdSize);
            processVpdMsg(sys,sys->pVpdMsg);
            pBuf+=vpdSize;
            restBytes-=vpdSize;
          //  PRINT_LINE;
            printf("%d %d \n",__LINE__,restBytes);
        }
        if(restBytes>0)
        {
            memcpy(sys->m_restBuf.buf,pBuf,restBytes);
            sys->m_restBuf.len=restBytes;
        }
    }
    return ;

}

static void * generateObjRResponse(void *sys,int objType,int *pSize)
{
	return NULL;
}
static void resetVPDStatus(vpdSystem *sys)
{

	stop_sound_module();
	sys->vpdStatus=STATUS_IDLE;

}
static void updateVPDParameters(vpdSystem *sys )
{
    //    sys->parameter.rawfftLen=sys->fftRange.FFT_FREQ_LEN;        //raw fft range
        sys->rawdataBufferSize=sys->parameter.curChannels*sys->parameter.onedataLen*sys->parameter.onedataSize;
        sys->onedataBufferSize=sys->parameter.onedataLen*sys->parameter.onedataSize;
        sys->rawfftBufferSize=sys->parameter.curChannels*sys->parameter.rawfftLen*sys->parameter.rawfftSize;
        sys->onefftBufferSize=sys->parameter.onefftLen*sys->parameter.onefftSize;


        sys->p_globalStRawData->channelsNums=sys->parameter.curChannels;
        sys->p_globalStRawData->samplesNums=sys->parameter.onedataLen;
        sys->p_globalStRawData->length=36+sys->rawdataBufferSize;
        sys->p_globalStRawData->head.length=sizeof(objStRawData)-8+sys->rawdataBufferSize;
        sys->p_globalStRawData->dataSize=sys->parameter.onedataSize;

        sys->p_globalStRawFFT->channelsNums=sys->parameter.curChannels;
        sys->p_globalStRawFFT->freqMin=sys->mSettings.freqMin;
        sys->p_globalStRawFFT->freqMax=sys->mSettings.freqMax;
        sys->p_globalStRawFFT->fftSize=sys->parameter.onefftSize;
        sys->p_globalStRawFFT->df=sys->parameter.fftDf;
        sys->p_globalStRawFFT->length=sys->rawfftBufferSize+27; //buffer Size
        sys->p_globalStRawFFT->head.length=sizeof(objStRawFFT)-8+sys->rawfftBufferSize;

        printf("%s fft: %d raw: %d \n",__func__,sys->p_globalStRawFFT->head.length, sys->p_globalStRawData->head.length);
        printf("%s %d %d %d index:%d \n",__func__,sys->rawdataBufferSize,sys->rawfftBufferSize,sys->onefftBufferSize,sys->mSettings.micIndex);
}
void processCmd(vpdSystem *sys,int cmd)
{
	printf("%s cmd:%d len:%d  \n",__func__,cmd);
	switch(cmd)
	{
	case MSG_START:
		sys->vpdStatus=STATUS_MEASURING;
		start_sound_module();
		sys->xStart = xTaskGetTickCount();	// get star time
		break;
	case MSG_STOP:
		stop_sound_module();
		sys->vpdStatus=STATUS_IDLE;
	default:
		break;
	}

}
int setSocketFd(vpdSystem *sys,int fd)
{
    sys->socketFd=fd;
    sys->vpdFirstCon=1;
	printf("%s  %d  %x \n",__func__,__LINE__,fd);
	return fd;
}
static void vpdSystemInit(vpdSystem *sys)
{
//	sys->p_vpdCtrl->soundModuleInit();
	sound_module_init();
	return ;
}
static void processData(vpdSystem *sys)
{
	printf("%s %d \n",__func__,__LINE__);

}
vpdSystem * createVpdSystem()
{
    vpdSystem *sys=malloc(sizeof(vpdSystem));

    sys->socketFd=NULL;
    sys->vpdFirstCon=0;
    sys->invokeId=0;
    sys->timestamps=0;
    sys->bufPos=0;
    sys->devNeedStatus=STATUS_IDLE;
    sys->devCurStatus=STATUS_IDLE;
    sys->devSubStatus=SUB_IDLE;
    sys->tcpSendMask.mRawdataEn=0;
    sys->tcpSendMask.mRawFFTEn=1;
    sys->tcpSendMask.mOnedataEn=1;
    sys->tcpSendMask.mOneFFTEn=1;
    sys->tcpSendMask.mPicEn=0;
    sys->tcpSendMask.mAcousEn=0;
    sys->m_rawdataTs=0;
    sys->m_rawfftTs=0;
    sys->objRR.obj.cmd=RES_CMD_READ_DATA_OBJECT;

    sys->pVpdMsg=malloc(sizeof(VPD_MESSAGE));
    sys->idInfo =vpd_indentification_init();
    sys->generateIdResponse=generateIdResponse;
    sys->generateObjRResponse=generateObjRResponse;
  //  sys->generateStatusResponse=generateStatusResponse;
    sys->parseAndReponseMessage=parseAndReponseMessage;

 //for generate data
    sys->generateRawData=generateRawData;
    sys->generateFFTData=generateFFTData;
    sys->generateJpegData=generateJpegData;
    sys->generateAcousData=generateAcousData;
    sys->generateOneData=generateOneData;
    sys->generateOneFFT=generateOneFFT;
    sys->generateObjReadResponse=generateObjReadResponse;
    sys->sendData=sendData;
    sys->sendReplyMessage=sendReplyMessage;
    sys->processCmd=processCmd;
    sys->setSocketFd=setSocketFd;
    sys->vpdSystemInit=vpdSystemInit;
    sys->resetVPDStatus=resetVPDStatus;
//
    sys->p_globalStRawData=objStRawDataHeadInit();
    sys->p_globalStRawFFT=objStRawFFTHeadInit();
    objStOtherHeadInit(sys);//init objStr jpeg onedata
   // sys->p_vpdCtrl=vpdControllerInit();


    sys->parameter.maxChannels=CHANNEL_MAX;
    sys->parameter.curChannels=CHANNEL_NUMS;
    sys->parameter.onedataLen=RAWDATA_LENS;
    sys->parameter.onedataSize=RAWDATA_SIZE;
	sys->parameter.rawfftLen=FFT_LENS;
    sys->parameter.rawfftSize=2;
    sys->parameter.onefftLen=FFT_LENS;
    sys->parameter.onefftSize=2;

    sys->mSettings.freqMin=0;
    sys->mSettings.micIndex=0;
    sys->mSettings.freqMin=5000;
    sys->mSettings.freqMax=10000;
    sys->mSettings.beamFPS=50;
    sys->headLen.LEN_RAW_DATA=sizeof(objStRawData)-OBJ_HEAD_TITLE;
    sys->headLen.LEN_ONE_DATA=sizeof(objStOneData)-OBJ_HEAD_TITLE;
    sys->headLen.LEN_RAW_FFT=sizeof(objStRawFFT)-OBJ_HEAD_TITLE;
    sys->headLen.LEN_ONE_FFT=sizeof(objStOneFFT)-OBJ_HEAD_TITLE;
    sys->headLen.LEN_JPEG=sizeof(objStJpeg)-OBJ_HEAD_TITLE;
    sys->headLen.LEN_ACOUS=sizeof(objStAcoustic)-OBJ_HEAD_TITLE;
    sys->headLen.LEN_COMMON_STAUS=sizeof(objStCommonStatus)-OBJ_HEAD_TITLE;
    sys->headLen.LEN_REPLY_MESSAGE=sizeof(objStReplyMessage)-OBJ_HEAD_TITLE;

    sys->headLen.BODY_RAW_DATA=sys->headLen.LEN_RAW_DATA-OBJ_BODY_TITLE;
    sys->headLen.BODY_ONE_DATA=sys->headLen.LEN_ONE_DATA-OBJ_BODY_TITLE;
    sys->headLen.BODY_RAW_FFT=sys->headLen.LEN_RAW_FFT-OBJ_BODY_TITLE;
    sys->headLen.BODY_ONE_FFT=sys->headLen.LEN_ONE_FFT-OBJ_BODY_TITLE;
    sys->headLen.BODY_JPEG=sys->headLen.LEN_JPEG-OBJ_BODY_TITLE;
    sys->headLen.BODY_ACOUS=sys->headLen.LEN_ACOUS-OBJ_BODY_TITLE;

    sys->fwInfo.length=0;
    sys->fwInfo.buf=NULL;
    sys->fwInfo.index=0;
    sys->fwInfo.upFlag=0;
    sys->fwInfo.upPercent=0;
    sys->m_restBuf.len=0;
  //  sys->mClearMask.nums=0;
    sys->m_coeBuf.index=0;
    sys->m_micMap.index=0;
    sys->fpgaErr=0;
    updateVPDParameters(sys);



    return sys;

}

resIdentification * vpd_indentification_init()
{
    resIdentification *idInfo=malloc(sizeof(resIdentification));
    printf("%s %d \n",__func__,sizeof(resIdentification));
    idInfo->cmd=RES_CMD_IDENTIFICATION;
    idInfo->status=0;
    idInfo->dataLength=sizeof(resIdentification)-12;
    idInfo->dataProtcolVersion=2;
    idInfo->deviceId=1;
    idInfo->deviceMode=1;
    idInfo->deviceError=0;
    idInfo->SNOfDevice=20231212;
    idInfo->SNOfSOM=0;
    idInfo->hwVersion=1.0;
    idInfo->bootloadVersion=0;
    idInfo->firmwareVersion=1;
    idInfo->fpgaVersion=1;
    idInfo->SNOfPCB=20231214;
    idInfo->invokeId=0;
    return idInfo;
}

